import java.util.Arrays;
import java.util.Map;
import java.util.Iterator;

class Directory extends ShellFile implements JSDirectory {

	private static final int MAX_FILES = 100;
	private static final String DEFAULT_NAME = "New Folder";
	public static final String isDir = true;

	private String name;
	private ShellList files;
	private int size;
	private JSDirectory parentDir;

	public Directory() {
		this("", null);
	}

	public Directory(JSDirectory parentDir) {
		this(DEFAULT_NAME, parentDir);
	}
	
	public Directory(String address, JSDirectory parentDir) {
		this(parseAddress(address), parentDir);
	}

	public Directory(String[] addressArray, JSDirectory parentDir) {
		
		// Decide name for directory based on address array
		String newName;
		if (addressArray.length == 0) {
			newName = "";
		} else {
			newName = addressArray[0];
		}
		
		// Main setup for the directory
		this.name = newName;
		this.parentDir = parentDir;
		this.files = new FileList();
		this.size = 0;
		
		// Create any additional directories within created directory
		if (addressArray.length > 1) {
			
			// Create a new array without the first directory
			// E.g. dir1/dir2/dir3 becomes dir2/dir3
			String[] continuedAddress = Arrays.copyOfRange(addressArray, 1, addressArray.length);
			
			// Create a new directory with this directory as its parent
			JSDirectory directoryWithin = new Directory(continuedAddress, this);
			
			// Add newly created array
			this.addDirectory(directoryWithin);
			
		}
	}

	public void setParentDir(JSDirectory parentDir) {
		this.parentDir = parentDir;
	}

	public void addDirectory(JSDirectory dirAdd) {

		// dirAdd needs to know this directory is its parent
		dirAdd.setParentDir(this);

		// Add dirAdd as if it were a file
		this.addFile((ShellFile) dirAdd);

	}

	public void addFile(ShellFile fileAdd) throws DirectoryException {

		// If folder is full, throw appropriate exception
		if (size == MAX_FILES) {
			String exceptionMessage = String.format("Error: %s is currently at " +
					"maximum capacity %d", name, MAX_FILES);
			throw new DirectoryFullException(); // Fix me to include message

		// Else, add fileAdd to the appropriate slot in files array,
		// and increment folder size
		} else {
			files.addFile(fileAdd);
		}

	}
	
	public boolean hasFile(String fileName) {
		return files.hasFile(fileName);
	}
	
	// Returns null if file not found
	public ShellFile getFile(String fileName) {
		return files.getFile(fileName);
	}
	
	public boolean isFull() {
		return (size == MAX_FILES);
	}

	public String getContents() {

		String result = new String();
		Iterator iterator = files.iterator();
		int spaces = 3;
		int j;
		
		for (Object entry : iterator) {
		    result = result + entry.getKey();
		
			// Append spaces according to spaces var
			for (j = 0; j < spaces; j++) {
				result = result + " ";
			}
			
		}

		// Trim last redundant spaces
		if (size > 0) {
			result = result.substring(0, (result.length() - spaces));
		}

		return result;

	}

	public String getAddress() {

		// If there is no parent dir, returened is "/"
		if (parentDir == null) {
			return "/";

		// If there is a parent dir, returned is "parentAddress/thisDir";
		// this is a recursive call, such that the result is the entire address
		} else {

			String parentName = parentDir.getAddress();

			if (parentName == "/") {
				return parentName + name;
			} else {
				return parentName + "/" + name;
			}

		}

	}
	
	public JSDirectory getParent() {
		return parentDir;
	}
	
	public JSDirectory getRoot() {
		
			// Preform a recursive call to find root directory
			if (parentDir == null) {
				return this;
			} else {
				return parentDir.getRoot();
			}

	}

	public String getName() {
		return name;
	}
	
	public static String[] parseAddress(String address) {
		return address.split("/");
	}
	
	public boolean isDir() {
		return isDir;
	}

	public static void main(String[] args) {
		
		// Test
		JSDirectory mDir = new Directory();
		JSDirectory childDir = new Directory("Folder1", mDir);
		JSDirectory childDir2 = new Directory("Folder2/FolderWithin", mDir);
		JSDirectory childDir3 = new Directory("Folder3", mDir);
		mDir.addDirectory(childDir);
		childDir.addDirectory(childDir2);
		mDir.addDirectory(childDir3);
		System.out.println(mDir.getContents());
		System.out.println(childDir2.getAddress());
		System.out.println(childDir2.getContents());
		
	}

}
